package org.icosagon.core.math;

import java.util.HashMap;
import java.util.Map;
import java.util.Vector;
import org.icosagon.core.character.Character;
import org.icosagon.core.character.traits.Skill;
import org.icosagon.core.character.Class;
import org.icosagon.core.character.traits.Ability;
import org.icosagon.core.character.traits.Feat;

/**
 * This class is used to calcuate and grab all of the values for
 * a character that are .
 * @author Daniel Owens
 */
public class CharacterEvaluator {
    private Character target = null;

    public CharacterEvaluator(Character character) {
        this.target = character;
    }

    public Vector<Skill> getSkills() {
        if(this.target == null)
            return null;

        HashMap<String,Integer> map = new HashMap<String,Integer>();
        Vector<Skill> skills = new Vector<Skill>();
        skills.addAll(this.target.getRace().getSkills());
        for(Class cl : this.target.getClasses()) {
            skills.addAll(cl.getSkills());
        }
        for(Skill skill : skills) {
            Integer value = map.get(skill.getName());
            if(value != null) {
                map.put(skill.getName(), new Integer(value.intValue()+skill.getValue()));
            }
        }
        skills = new Vector<Skill>();
        for(Map.Entry<String, Integer> entry : map.entrySet()) {
            Skill skill = new Skill(entry.getKey());
            skill.setValue(entry.getValue().intValue());
            skills.add(skill);
        }
        return skills;
    }

    public int getSkill(String name) {
        if(this.target == null || name == null)
            return 0;

        int value = 0;
        Vector<Skill> skills = new Vector<Skill>();
        skills.addAll(this.target.getRace().getSkills());
        for(Class cl : this.target.getClasses()) {
            skills.addAll(cl.getSkills());
        }
        for(Skill skill : skills) {
            if(skill.getName().equals(name))
                value += skill.getValue();
        }
        return value;
    }

    public Vector<Ability> getAbilities() {
        if(this.target == null)
            return null;

       Vector<Ability> abilities = this.target.getAbilities();
       for(Ability ability : this.target.getRace().getAbilitiesModifiers()) {
           for(Ability compare : abilities) {
               if(compare.getName().equals(ability.getName())) {
                   int value = compare.getValue() + ability.getValue();
                   compare.setValue(value);
               }
           }
       }
       return abilities;
    }

    /**
     * Returns the value for an ability.
     * @param name The name of the ability that the value will be returned for.
     * @return The value of the ability being looked for.
     */
    public int getAbility(String name) {
        if(this.target == null || name == null)
            return 0;

        int value = 0;
        for(Ability ability : this.target.getAbilities()) {
            if(ability.getName().equals(name))
                value += ability.getValue();
        }
        for(Ability ability : this.target.getRace().getAbilitiesModifiers()) {
            if(ability.getName().equals(name))
                value += ability.getValue();
        }
        return value;
    }

    public Vector<Feat> getFeats() {
        if(this.target == null)
            return null;
        Vector<Feat> feats = new Vector<Feat>();
        feats.addAll(this.target.getFeats());
        feats.addAll(this.target.getRace().getFeats());
        for(Class cl : this.target.getClasses()) {
            feats.addAll(cl.getFeats());
        }
        return feats;
    }
}